# Create your views here.
from django.views.generic.base import View
from django_redis import get_redis_connection
from django import http
from random import randint

from . import constants
from meiduo_mall.libs.captcha.captcha import captcha
from meiduo_mall.utils.response_code import RETCODE
from celery_tasks.sms.tasks import send_sms_code


import logging

logger = logging.getLogger("django")



class ImageCodeView(View):
    """图形验证码"""

    def get(self, request, uuid):
        """返回图形验证码的图形请求"""

        # 提取uuid参数
        # 验证参数（忽略）

        # 生产图形验证码
        name, text, image = captcha.generate_captcha()

        # 链接redis数据库
        redis_conn = get_redis_connection("verify_code")

        # 存储数据到redis中，uuid作为key，存储4位验证码的值
        # 300 -> 5 分钟后数据无效；300这个常量我们可以定义一个变量去优化。
        # 否则300代表什么，很容易忘记。
        redis_conn.setex(uuid, constants.IMAGE_CODE_REDIS_EXPIRES, text)

        # 返回图形验证码的图片 bytes类型
        return http.HttpResponse(image, content_type="image/jpg")



# GET /sms_codes/13123456712/?image_code=ljeu&uuid=e05871ca-4b2d-4e5d-bc66-13f635fb1bb6
class SmsCodeView(View):
    """短信验证码验证视图"""

    def get(self, request, mobile):
        # get请求发送短信验证码

        #   链接redis数据库
        redis_conn = get_redis_connection("verify_code")

        send_flag = redis_conn.get("send_flag_%s" % mobile)
        #   读取send_flag_mobile标志，来判断当前号码是否频繁发送短信
        if send_flag:
            return http.JsonResponse({'code':RETCODE.THROTTLINGERR, 'errmsg':"频繁发送短信验证码"})

        # 1.接收参数
        # image_code_client: 客户输入的图形验证码
        # uuid：redis数据库中通过uuid这个key记录验证码
        image_code_client = request.GET.get("image_code")
        uuid = request.GET.get("uuid")

        # if not all([image_code_client, uuid]):
        if all([image_code_client, uuid]) is False:
            return http.HttpResponse("缺少必须输入的项（验证码）")

        # 2.校验参数

        #   取出uuid对应的图形验证码
        image_code_server = redis_conn.get(uuid)

        # pipeline使用get获取redis数据库数据（pl.get不会马上获取结果），需要执行pl.execute才能执行并获取结果（列表）
        # pl.get(uuid)
        # list = pl.execute()

        if image_code_server is None:
            return http.HttpResponse("验证码过期或者无效")

        #   删除redis中的图形验证码
        redis_conn.delete(uuid)

        #   把redis中记录的验证码和客户输入的验证码进行比对
        #       转换bytes类型成字节类型
        image_code_server = image_code_server.decode()
        if image_code_client.lower() != image_code_server.lower():
            return http.HttpResponse("验证码输入错误")


        # 3.发送短信验证码
        #   1.生产6位随机的短信验证码
        sms_msg = "%06d" % randint(0, 999999)


        # 使用管道pipeline提高redis效率：
        #   创建pipeline管道对象
        pl = redis_conn.pipeline()

        #   2.0保持短信验证码(到redis数据库）
        # redis_conn.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_msg)
        pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_msg)

        #   2.1保存手机发送标志到redis数据库
        # redis_conn.setex("send_flag_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        pl.setex("send_flag_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)

        # 执行管道中的redis命令
        pl.execute()

        # #   3.发送短信验证码
        # #   CCP.send_template_sms(发送的电话号码, [6位短信验证码, 提示过期时间（单位分钟）], 短信模板)
        # #
        # #   需要优化：客户端 -> 容联云 -> 发送短信 （这个过程中我们没有必要等待短信发送成功）
        # CCP().send_template_sms(mobile, [sms_msg, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)

        # 生产任务 加入异步任务队列
        send_sms_code.delay(mobile, sms_msg)


        # 输出日志信息到文件和终端
        logger.info(sms_msg)

        # 4.返回响应
        return http.JsonResponse({"code": RETCODE.OK, "errmsg": "发送验证码成功"})

